﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class EntitySolider : BattleEntity
{
    public GameObject m_pGameObj;
    public GameObject m_pRender;
    public AnimationComp m_pAnimation;
    public int m_iSoliderId;
    public string m_strModelPath;
    private bool m_bLeft;
    private int m_iInTroopIndex;

    List<SteerBase> lisSteers;
    Dictionary<string, SteerBase> dicSteers;
    Vehicle m_pVeh;
    private NStateMachine<EntitySolider> m_pStateMachine;

    public bool Alive
    {
        get { return true; }
    }
    public Vehicle Veh
    {
        get { return m_pVeh; }
    }

    public override void OnCreate(params object[] args)
    {
        m_iSoliderId = (int)args[0];
        m_strModelPath = (string)args[1];
        m_bLeft = (bool)args[2];
        m_iInTroopIndex = (int)args[3];
        m_pGameObj = new GameObject();
        m_pGameObj.transform.localScale = Vector3.one;
        m_pGameObj.name = "Solider_" + m_iInTroopIndex.ToString();

        m_pRender = GameObject.Instantiate<GameObject>(GetModel());
        m_pRender.name = "Model";
        m_pRender.transform.localScale = Vector3.one;
        m_pRender.transform.localEulerAngles = Vector3.zero;
        m_pRender.transform.localScale = Vector3.one;
        m_pRender.transform.SetParent(m_pGameObj.transform);
        m_pGameObj.layer = LayerMask.NameToLayer(BattleDef.LayerName_3dObj);
        m_pGameObj.transform.forward = BattleDef.GetDirByBLeft(m_bLeft);

        Animation ani = m_pRender.GetComponentInChildren<Animation>();
        m_pAnimation = new AnimationComp(ani, AnimationEnd);

        if (lisSteers == null)
            lisSteers = new List<SteerBase>();
        if (dicSteers == null)
            dicSteers = new Dictionary<string, SteerBase>();

        lisSteers.Clear();
        dicSteers.Clear();
        List<string> steers = new List<string>()
        {
            SteerName.StN_SteerSeparation,
            SteerName.StN_SteerForPoint,
            SteerName.StN_SteerFlee,
            SteerName.StN_SteerForward
        };
        for (int i = 0; i < steers.Count; i++)
        {
            SteerBase steer = m_pGameObj.AddComponent(Type.GetType(steers[i])) as SteerBase;
            steer.enabled = false;
            lisSteers.Add(steer);
            dicSteers.Add(steers[i], steer);
        }
        m_pVeh = m_pGameObj.AddComponent<Vehicle>();
        m_pVeh.Init(1);
        m_pVeh.GetSteers();

        Dictionary<string, NState<EntitySolider>> state = new Dictionary<string, NState<EntitySolider>>()
        {
            {SoliderStateDef.StandBy,SoliderStateDef.s_stateStandby },
            {SoliderStateDef.MovePoint,SoliderStateDef.s_stateMovePoint },
            {SoliderStateDef.Search,SoliderStateDef.s_stateSearch },
            {SoliderStateDef.Attack,SoliderStateDef.s_stateAttack },
        };
        m_pStateMachine = new NStateMachine<EntitySolider>(this, state, SoliderStateDef.StandBy);
        m_pStateMachine.ChangeState(SoliderStateDef.StandBy);
    }

    private void AnimationEnd(string clipName, int num)
    {

    }

    private GameObject GetModel()
    {
        return (GameObject)Resources.Load(m_strModelPath);
    }

    public override void OnUpdate(float deltaTime)
    {
        base.OnUpdate(deltaTime);

        m_pAnimation.OnUpdate(deltaTime);
        m_pVeh.FreshRadar();
        m_pVeh.CalculateForces();
        m_pVeh.UpdatePos(deltaTime);
    }

    public void ChangeState(string state, params object[] args)
    {
        m_pStateMachine.ChangeState(state, args);
    }

    /// <summary>
    /// 跑向某个点
    /// </summary>
    /// <param name="pos">某个点</param>
    /// <param name="onArrival">到达之后的回调</param>
    /// <param name="bCollision">是否需要开启碰撞</param>
    public void Go(Vector3 pos, System.Action<SteerBase> onArrival, bool bCollision = false)
    {
        m_pVeh.SetSteerForPoint(pos, onArrival);
        m_pVeh.SetSteerState(SteerName.StN_SteerSeparation, bCollision);
    }

    /// <summary>
    /// 播放动画
    /// </summary>
    /// <param name="clipName">动画剪辑名字</param>
    /// <param name="isLoop">是否循环</param>
    public void PlayClip(string clipName, bool isLoop)
    {
        m_pAnimation.Play(clipName, isLoop);
    }
}
